﻿using System;
using Enyim.Caching;
using Enyim.Caching.Memcached;
using NLog;
using LogManager = NLog.LogManager;

namespace CoreLibrary.Cache {

    public class EnyimCache : AbstractCache {
        
        protected override void OnStart(){}
        protected override void OnStop() {}

        private readonly Logger _logger = LogManager.GetCurrentClassLogger();
        private MemcachedClient _cache;

        protected override void OnInit() {
            _cache = new MemcachedClient();
        }

        protected override void OnDestroy() {
            if (_cache != null) {
                _cache.Dispose();
                _cache = null;
            }
        }

        protected override CacheItem<T> GetItem<T>(string key) {
            var value = _cache.Get(key);
            if (value == null) {
                return new CacheItem<T>(false, default(T)) {
                    Key = key
                };
            }
            if (value is T == false) {
                _logger.Error("The value of key#" + key + " is " + value.GetType().Name + ", expected " + typeof(T).Name);
                return new CacheItem<T>(false, default(T)) {
                       Key = key
                };
            }

            return new CacheItem<T>(true, (T)value) {
                   Key = key
            };
        }

        public override void Remove(string key) {
            _cache.Remove(key);
        }

        public override void Put(string key, object value) {
            _cache.Store(StoreMode.Set, key, value);
        }

        public override void Put(string key, object value, TimeSpan expiration) {
            /**
             * Amazon cache server is found to use different date/time than Sydney, which resulted in
             * immediate expiration on item when the expiration is set to short time such as a few mins.
             * 
             * Since we don't have direct access to the cache server, can't verify what timezone it is in...
             * 
             * A workaround is to add 24 hours to the give expiration 
             */
            _cache.Store(StoreMode.Set, key, value, expiration.Add(TimeSpan.FromHours(24)));
        }
    }
}